package fm.last
{
    import flash.events.ErrorEvent;
    
    import memorphic.xpath.XPathQuery;
    
    import unitest.TestCase;

    /** Base class for all test cases. */
    public class BaseTC extends TestCase
    {
        /* ***************************************************************** */
        /*     You may want to your own keys                                 */
        /*                                                                   */
        public static const _api_key:String = "74df396974b4b98facd7da625d24cf29";
        public static const _secret:String = "46c5ea8b85868cbae18711910d6db148";
        public static const _sk:String = "df96e7e4a697d5b47d0297ff485aac93";
        
        // XXX: manualy get it before testing AuthAPITest!!!
        public var _a_token:String = null;
        /*                                                                   */
        /*                                                                   */
        /* ***************************************************************** */
        
        
        /* ***********************************************************/
        
        /** services instance */        
        protected var lfm_service:LastFmService = null;
        
        /* ***********************************************************/
        
        /* some handy callback function to do assertion */
        
        /** 
        * 
        * A callback function that checks an OK response without content.
        * e.g. expected response &lt;lfm status="ok"&gt;&lt;/lfm&gt;.
        * 
        */
        protected var okNoContent:Function =                 
                function(response:XML):void {              
                    if (response.toString()!= "" || 
                        response.attribute("status") != "ok") 
                        fail("okNoContent failed: " + response);                               
                };                 
                
          
        /**
        * 
        * create a callback function that checks OK (or FAILED) response with matching content.
        * 
        * @param query    the XPath query to evalate
        * @param expected expected value. If null, it will match all none-blank charaters i.e. /\S/.
        */  
        protected function expectedPattern(query:String,expected:RegExp=null):Function 
        { 
                return function(response:XML):void {
                    
                    if (response.attribute("status") != "ok" && 
                        response.attribute("status") != "failed") {
                        fail("expectedComplete failed: " + cut(response,20));
                    }
                    
                    if (query!=null) {
                        // try match query!
                        
                        var xpq:XPathQuery = new XPathQuery(query);
                        var xpq_result:XMLList = xpq.exec(response);
                        expected = (expected==null?/\S/:expected);
                        
                        //trace("[expected pattern] query: " + 
                        //            query + ";  retrieved content: " + xpq_result + 
                        //            "; source xml: " + response);
                                    
                        if (xpq_result.toString().search(expected)<0) {
                            fail("[expected pattern failed] [query: " + query + "]; " +
                                 " [expected: " +  expected + "]; " +  
                                 " [retrieved content: " + cut(xpq_result) + "]; " +
                                 " [source xml: " + cut(response) + "]");
                        }
                    } else {
                        // no query is given
                        // we print out the response
                                        
                        var str:String = response.toString();                    
                        trace("[DEBUG] expected complete  : " + cut(str));
                    }
                };
        };
                
        protected var unexpectedComplete:Function = 
                function(response:XML):void {
                    fail("[ERROR] unexpected complete with: " + response); 
                };                

        protected var expectedError:Function = 
                function(e:ErrorEvent):void {
                    //trace("[DEBUG] expected error with: " + e);       
                };
                
        protected var unexpectedError:Function = 
                function(e:ErrorEvent):void {
                    fail("[ERROR] unexpected error with: " + e); 
                };     
                        
        /* ***********************************************************/
                                
        public function BaseTC() 
        {
            super();
            lfm_service = new LastFmService(_api_key, _secret, _sk);
        }
        
        private static function cut(s:String, len:int=300):String
        {
            return (s.substr(0, len) + 
                              (s.length>len?" ......\n......[ cut ]":""));
        }
    }
}